HmJS.$Import('core.core');

/*
---
version: 0.1-0
description: Rails Time syntax provider for mootools
license: MIT-style
download: http://mootools.net/forge/p/time
source: http://github.com/arieh/Time/

authors:
- Arieh Glazer

requires:
- core/1.2.4 : [Class, Object]

provides: [Time, Number.Time, Date.Time]
...
*/

HmJS.register('util.Time', function ($ns) {

	var states = {
		'seconds': 1000,
		'minutes': 1000 * 60,
		'hours': 1000 * 60 * 60,
		'days': 1000 * 60 * 60 * 24,
		'weeks': 1000 * 60 * 60 * 24 * 7,
		'months': false,
		'years': 1000 * 60 * 60 * 24 * 365
	};

	var subs = function (n1, n2) {
		return n1 - n2;
	};

	var add = function (n1, n2) {
		return n1 + n2;
	};

	var Time = new Class({
		number: 0,
		state: 'seconds',
		date: null,
		initialize: function initialize(num, date) {
			this.number = num;
			this.date = date;
			var $this = this;

			Object.each(states, function (value, name) {
				$this[name] = function (num) {
					if (num) this.number = num;
					$this.state = name;
					return $this;
				};
			});
		},

		calculate: function calculate(action) {
			var date = this.date || new Date,
           time = +date,
           i,
           day = date.getDate(),
           month = date.getMonth(),
           year = date.getFullYear();

			switch (this.state) {
				case 'seconds':
				case 'minutes':
				case 'hours':
				case 'days':
				case 'weeks':
					for (i = 0; i < this.number; i++) {
						time = action(time, states[this.state]);
					}
					return new Date(time);
					break;

				case 'months':
					month = action(month, this.number);
					if (month > 11) {
						date.setMonth(month % 11);
						date.setFullYear(action(year, Math.floor(month / 11)));
					} else if (month < 0) {
						date.setMonth(month * -1 % 11);
						date.setFullYear(action(year, Math.floor(month * -1 / 11)));
					} else {
						date.setMonth(month);
					}
					return date;
					break;

				case 'years':
					date.setFullYear(action(year, this.number));
					break;
			}

		},

		from_now: function from_now() {
			return this.calculate(add);
		},

		ago: function ago() {
			return this.calculate(subs);
		}

	});

	Object.each(states, function (value, action) {
		Number.implement(action, function () {
			this.time = new Time(this);
			return this.time[action]();
		});

		Date.implement(action, function (num) {
			this.time = new Time(num || 0, this);
			return this.time[action]();
		});
	});

	return Time;
});  
